home *** CD-ROM | disk | FTP | other *** search
/ Aminet 44 / Aminet 44 (2001)(GTI - Schatztruhe)[!][Aug 2001].iso / Aminet / comm / misc / Sashi89.lha / Sashi89 / sources / hard.c < prev    next >
C/C++ Source or Header  |  2001-05-08  |  10KB  |  515 lines

  1. /*
  2.  
  3.     This file handle the low-level communication.
  4.     It supports both usual Parallel port and the $4 serial link.
  5.     Just put HARD_VERSION = HARD_VERSION_PAR or HARD_VERSION_SER
  6.     to switch between them
  7. */
  8.  
  9.  
  10. //#define DEBUG
  11. //#define STAT
  12.  
  13. #define HARD_VERSION_PAR 1
  14. #define HARD_VERSION_SER 2
  15.  
  16. #define HARD_VERSION HARD_VERSION_SER
  17.  
  18.  
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21.  
  22. /* Amiga */
  23. /* Hardware : */
  24. #include <exec/types.h>
  25. #include <hardware/cia.h>
  26.  
  27. /* System : */
  28. #include <exec/types.h>
  29. #include <exec/memory.h>
  30. #include <dos/dos.h>
  31. #include <devices/serial.h>
  32. #include <devices/parallel.h>
  33. #include <proto/dos.h>
  34. #include <proto/exec.h>
  35.  
  36. #include "hard.h"
  37.  
  38. /* Two lines between computer and calc : */
  39.  
  40. #define LINE1 1
  41. #define LINE2 2
  42.  
  43.  
  44. #if HARD_VERSION == HARD_VERSION_SER
  45. #elif HARD_VERSION == HARD_VERSION_PAR
  46. #endif
  47.  
  48.  
  49. /* Two states for each line : */
  50. #define HIGH  0
  51. #define LOW   1
  52.  
  53.  
  54.  
  55. /* Assert a state on a line : */
  56. inline void   ti_setline(int value, UBYTE where);
  57. /* Get state of a line : */
  58. inline UBYTE  ti_getline(UBYTE where);
  59.  
  60.  
  61. /* Amiga Specific : */
  62. extern struct CIA ciaa, ciab;
  63. struct MsgPort  *SerialMP=NULL;     /* Message port pointer */
  64. struct IOExtSer *SerialIO=NULL;    /* I/O request pointer */
  65.  
  66. struct MsgPort  *ParallelMP=NULL;     /* Message port pointer */
  67. struct IOExtPar *ParallelIO=NULL;    /* I/O request pointer */
  68.  
  69. /* Keep state in static, so that we can remember what we did at init,
  70.      and what we didn't
  71. */
  72. static int state=0;
  73. #define STATE_PORT  1
  74. #define STATE_EXTIO 2
  75. #define STATE_DEV   4
  76.  
  77.  
  78.  
  79.  
  80. /*
  81.     Timer stuff
  82.     We use timer only for timeout or retry delays
  83. */
  84. #include "timer.h"
  85. Timer_Info time_info;
  86.  
  87.  
  88. #define HARD_MAX_TRY_ACTIVE     100
  89. #define HARD_MAX_TRY            (HARD_MAX_TRY_ACTIVE+30)
  90.  
  91. /* Wait after retrying, if the calc. does not ack enough quickly */
  92. #define WAIT_RETR timer_delay(&time_info,10000)
  93.  
  94. /* Wait if a timeout occures : */
  95. #define WAIT_TIMEOUT timer_delay(&time_info,200000)
  96.  
  97.  
  98. /*
  99.     if debug_mode == 0 then we are system compliant : ask for device
  100.     Otherwise, we are not
  101. */
  102. extern int debug_mode;
  103.  
  104.  
  105. char *ti_version(void )
  106. {
  107. #if HARD_VERSION == HARD_VERSION_SER
  108.     return("serial version ("__DATE__")");
  109. #elif HARD_VERSION == HARD_VERSION_PAR
  110.     return("parallel version ("__DATE__")");
  111. #endif
  112.  
  113. }
  114. int ti_openport(void )
  115. {
  116.   if ( ! debug_mode )
  117.   {
  118. #if HARD_VERSION == HARD_VERSION_SER
  119.         /* Ask for the serial port */
  120.       if (  !( SerialMP=CreatePort(NULL,0)) )
  121.       {
  122.         printf(__FILE__"> CreatePort failed.\n");
  123.         ti_closeport();
  124.         return(1);
  125.       }
  126.       state += STATE_PORT;
  127.  
  128.       if ( !( SerialIO=(struct IOExtSer *)CreateExtIO(SerialMP,sizeof(struct IOExtSer)) ) )
  129.       {
  130.         printf(__FILE__"> Unable to open SerialIO.\n");
  131.         ti_closeport();
  132.         return(1);
  133.       }
  134.       state += STATE_EXTIO;
  135.  
  136.       if ( OpenDevice(SERIALNAME,0L,(struct IORequest *)SerialIO,0))
  137.       {
  138.         printf(__FILE__"> Unable to open serial port ( %s unit 0 )\n",SERIALNAME);
  139.         ti_closeport();
  140.         return(1);
  141.       }
  142.       state += STATE_DEV;
  143. #elif HARD_VERSION == HARD_VERSION_PAR
  144.         /* Ask for the parallel port */
  145.         if ( ! ( ParallelMP=CreatePort(NULL,0)  ) )
  146.       {
  147.         printf(__FILE__"> CreatePort failed.\n");
  148.         ti_closeport();
  149.         return(1);
  150.       }
  151.       state += STATE_PORT;
  152.         
  153.         if ( ! ( ParallelIO=(struct IOExtPar *)CreateExtIO(ParallelMP,sizeof(struct IOExtPar)) ) )
  154.       {
  155.             printf(__FILE__"> Unable to open ParallelIO.\n");
  156.         ti_closeport();
  157.         return(1);
  158.       }
  159.       state += STATE_EXTIO;
  160.  
  161.         if (OpenDevice(PARALLELNAME,0L,(struct IORequest *)ParallelIO,0) )
  162.       {
  163.             printf(__FILE__"> Unable to open parallel port ( %s unit 0 )\n",PARALLELNAME);
  164.         ti_closeport();
  165.         return(1);
  166.       }
  167.       state += STATE_DEV;
  168. #endif
  169.   }
  170.     /* We now have the serial or paralle device for ourselves */
  171.   ti_initport();
  172.  
  173.  
  174.   if ( timer_create(&time_info) )
  175.   {
  176.     printf(__FILE__"> Error creating timer\n");
  177.     ti_closeport();
  178.     return(1);
  179.   }
  180.  
  181.   return(0); /* No error */
  182. }
  183.  
  184. void ti_closeport(void )
  185. {
  186.   ti_initport();
  187.   if ( ! debug_mode )
  188.   {
  189. #if HARD_VERSION == HARD_VERSION_SER
  190.     if ( state & STATE_DEV )
  191.       CloseDevice((struct IORequest *)SerialIO);
  192.  
  193.     if ( state & STATE_EXTIO )
  194.       DeleteExtIO((struct IORequest *)SerialIO);
  195.     if ( state & STATE_PORT )
  196.       DeletePort(SerialMP);
  197. #elif HARD_VERSION == HARD_VERSION_PAR
  198.     if ( state & STATE_DEV )
  199.             CloseDevice((struct IORequest *)ParallelIO);
  200.  
  201.     if ( state & STATE_EXTIO )
  202.             DeleteExtIO((struct IORequest *)ParallelIO);
  203.     if ( state & STATE_PORT )
  204.             DeletePort(ParallelMP);
  205. #endif
  206.   }
  207.   timer_delete(&time_info);
  208.   state = 0;
  209. }
  210.  
  211.  
  212. inline void ti_setline(int value, UBYTE where)
  213. {
  214. #if HARD_VERSION == HARD_VERSION_SER
  215.     if ( where == LINE1 )
  216.         where = CIAF_COMRTS;
  217.     else
  218.         where = CIAF_COMDTR;
  219.  
  220.     if ( value == LOW )
  221.     ciab.ciapra=ciab.ciapra|where;
  222.   else
  223.     ciab.ciapra=ciab.ciapra&(where^0xFF);
  224. #elif HARD_VERSION == HARD_VERSION_PAR
  225.     if ( where == LINE1 )
  226.         where = 2;
  227.     else
  228.         where = 1;
  229.  
  230.     if ( value == HIGH )
  231.         ciaa.ciaprb|=where;
  232.   else
  233.         ciaa.ciaprb&=(where^0xFF);
  234. #endif
  235. }
  236.  
  237.  
  238.  
  239. inline UBYTE ti_getline(UBYTE where)
  240. {
  241. #if HARD_VERSION == HARD_VERSION_SER
  242.     if ( where == LINE1 )
  243.         where = CIAF_COMCTS;
  244.     else
  245.         where = CIAF_COMDSR;
  246.  
  247.   if ( ciab.ciapra&where )
  248.         return(LOW);
  249.   else
  250.         return(HIGH);
  251. #elif HARD_VERSION == HARD_VERSION_PAR
  252.     if ( where == LINE1 )
  253.         where = CIAF_PRTRSEL;
  254.     else
  255.         where = CIAF_PRTRPOUT;
  256.  
  257.     if ( ciab.ciapra&where )
  258.         return(HIGH);
  259.   else
  260.         return(LOW);
  261. #endif
  262.  
  263. }
  264.  
  265.  
  266. inline void ti_initport(void )
  267. {
  268. #if HARD_VERSION == HARD_VERSION_SER
  269.     ti_setline(HIGH,LINE1);
  270.     ti_setline(HIGH,LINE2);
  271.   ciaa.ciaddrb = 0xc0;
  272.  
  273. #elif HARD_VERSION == HARD_VERSION_PAR
  274.     ciaa.ciaddrb = 0x03;
  275.     ciab.ciaddra = 0x00;
  276.     ti_setline(HIGH,LINE1);
  277.     ti_setline(HIGH,LINE2);
  278. #endif
  279. }
  280.  
  281.  
  282. inline int ti_sendbit(UBYTE bit )
  283. {
  284.   int where1, where2;
  285.     unsigned long int count;
  286.  
  287.   if ( bit )
  288.   {
  289.         where1 = LINE2;
  290.         where2 = LINE1;
  291.   }
  292.   else
  293.   {
  294.         where1 = LINE1;
  295.         where2 = LINE2;
  296.   }
  297.  
  298.   ti_setline(LOW,where1);
  299.  
  300.     count=0;
  301.     do
  302.     {    if ( ++count >= HARD_MAX_TRY_ACTIVE )
  303.             WAIT_RETR;
  304.   }
  305.     while ( ti_getline(where2) != LOW && count <= HARD_MAX_TRY );
  306.  
  307.   if ( count > HARD_MAX_TRY )
  308.   {
  309. #ifdef DEBUG
  310.         printf(__FILE__"> sendbit Timeout send 1 (%ld)\n",count);
  311. #endif
  312.     WAIT_TIMEOUT;
  313.     return(HARD_TIMEOUT);
  314.   }
  315.  
  316. #ifdef STAT
  317.   printf(__FILE__"> sendbit Acquittement recu , count=%ld\n",count);
  318. #endif
  319.   ti_setline(HIGH,where1);
  320.  
  321.   count = 0;
  322.     do
  323.     {    if ( ++count >= HARD_MAX_TRY_ACTIVE )
  324.             WAIT_RETR;
  325.   }
  326.     while ( ti_getline(where2) != HIGH && count <= HARD_MAX_TRY );
  327. #ifdef STAT
  328.   printf(__FILE__"> sendbit Fin acquittement recu , count=%ld\n",count);
  329. #endif
  330.  
  331.   if ( count > HARD_MAX_TRY )
  332.   {
  333. #ifdef DEBUG
  334.     printf(__FILE__"> sendbit Timeout send 2 (%ld)\n",count);
  335. #endif
  336.     WAIT_TIMEOUT;
  337.     return(HARD_TIMEOUT);
  338.   }
  339.  
  340.   return(0);
  341. }
  342.  
  343. inline int ti_recvbit(UBYTE *result )
  344. {
  345.   unsigned long int count,count2;
  346.  
  347.   count2 = 0;
  348.  
  349.   do
  350.   {
  351.         if ( ti_getline(LINE1) == LOW )
  352.     {
  353. #ifdef STAT
  354.             printf(__FILE__"> recvbit CTS==LOW count=%ld\n",count2);
  355. #endif
  356.             ti_setline(LOW,LINE2);
  357.  
  358.  
  359.       count=0;
  360.             do
  361.             {    if ( ++ count >= HARD_MAX_TRY_ACTIVE )
  362.           WAIT_RETR;
  363.       }
  364.             while ( ti_getline(LINE1) == LOW && count <= HARD_MAX_TRY );
  365.  
  366.             ti_setline(HIGH,LINE2);
  367.             /* We just make sure that our previous order is on the line : */
  368.             count = 0;
  369.             do {count++;}while(ti_getline(LINE2)!=HIGH&&count<HARD_MAX_TRY_ACTIVE);
  370.  
  371.       *result = 0;
  372.  
  373.       if ( count > HARD_MAX_TRY )
  374.       {
  375. #ifdef DEBUG
  376.         printf(__FILE__"> Timeout recv A (%ld)\n",count);
  377. #endif
  378.         WAIT_TIMEOUT;
  379.         return(HARD_TIMEOUT);
  380.       }
  381.  
  382.       return(0);
  383.     }
  384.  
  385.         if ( ti_getline(LINE2) == LOW )
  386.     {
  387. #ifdef STAT
  388.             printf(__FILE__"> recvbit DSR==LOW count=%ld\n",count2);
  389. #endif
  390.             ti_setline(LOW,LINE1);
  391.  
  392.  
  393.       count=0;
  394.             do
  395.             {
  396.                 if ( ++count >= HARD_MAX_TRY_ACTIVE )
  397.           WAIT_RETR;
  398.       }
  399.             while ( ti_getline(LINE2) == LOW && count <= HARD_MAX_TRY );
  400.  
  401.             ti_setline(HIGH,LINE1);
  402.  
  403.             count = 0;
  404.             do {count++;} while(ti_getline(LINE1)!=HIGH&&count<HARD_MAX_TRY_ACTIVE);
  405. #ifdef STAT
  406.             printf(__FILE__"> recvbit result=1, count=%ld\n",count);
  407. #endif
  408.  
  409.       *result = 1;
  410.  
  411.  
  412.       if ( count > HARD_MAX_TRY )
  413.       {
  414. #ifdef DEBUG
  415.         printf(__FILE__"> rB%ld\n",count);
  416.         printf(__FILE__"> Timeout recv B (%ld)\n",count);
  417. #endif
  418.         WAIT_TIMEOUT;
  419.         return(HARD_TIMEOUT);
  420.       }
  421.  
  422.       return(0);
  423.     }
  424.         /*if ( count2 >= HARD_MAX_TRY_ACTIVE )
  425.             WAIT_RETR;*/
  426.     count2++;
  427.   }
  428.     while(count2<100*HARD_MAX_TRY);
  429.  
  430. #ifdef DEBUG
  431.   printf(__FILE__"> Timeout recv C (%ld)\n",count2);
  432. #endif
  433.   ti_initport();
  434.     //WAIT_TIMEOUT;
  435.   return(HARD_TIMEOUT);
  436. }
  437.  
  438. int ti_recvbyte(UBYTE *result )
  439. {
  440.   int cpt;
  441.   UBYTE temp;
  442.  
  443.   *result=0;
  444.  
  445.   for ( cpt=0; cpt<BITS_PER_BYTE; cpt++)
  446.   {
  447.     if ( ti_recvbit(&temp) == HARD_TIMEOUT )
  448.     {
  449. #ifdef DEBUG
  450.             printf("bytes.c> Error (r) on bit %d\n",cpt);
  451. #endif
  452.       return(BYTE_ERROR);
  453.     }
  454. #ifdef LOG
  455.     //printf("%d",temp);
  456. #endif
  457.     *result=*result | ( temp << cpt );
  458.   }
  459.  
  460. #ifdef DEBUG
  461.   if ( isalpha(*result) )
  462.         printf("Log> Got %2X (%c)\n",*result,*result);
  463.   else
  464.         printf("Log> Got %2X\n",*result);
  465. #endif
  466.  
  467.     //WAIT_RETR;
  468.  
  469.   return(0);
  470. }
  471.  
  472. int ti_sendbyte(UBYTE byte)
  473. {
  474.   int cpt=0;
  475.  
  476. #ifdef DEBUG
  477.  if ( isalpha(byte) )
  478.         printf("Log> Put %2X (%c)\n",byte,byte);
  479.   else
  480.         printf("Log> Put %2X\n",byte);
  481. #endif
  482.  
  483.   for ( cpt=0; cpt<BITS_PER_BYTE; cpt++)
  484.   {
  485.     //printf("%d",byte&1);
  486.     if ( ti_sendbit( byte & 1 ) == HARD_TIMEOUT )
  487.     {
  488. #ifdef DEBUG
  489.       printf("bytes.c> Erreur (s) sur le bit %d\n",cpt);
  490. #endif
  491.       return(BYTE_ERROR);
  492.     }
  493.     byte = byte >> 1;
  494.   }
  495.     //WAIT_RETR;
  496.   return(0);
  497.  
  498. }
  499.  
  500. int ti_sendbytes(UBYTE *bytes,int nb)
  501. {
  502.   int cpt;
  503.  
  504.   for ( cpt=0; cpt<nb; cpt++)
  505.   {
  506.     if ( ti_sendbyte(bytes[cpt]) == BYTE_ERROR )
  507.       return(BYTE_ERROR);
  508.   }
  509.   return(0);
  510.  
  511. }
  512.  
  513.  
  514.  
  515.